{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This notebook shows how to use `tfe.queue.FIFOQueue`."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Setup"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import tensorflow as tf\n",
    "import tf_encrypted as tfe\n",
    "\n",
    "from utils import print_in_notebook"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Turn on TFE profling flags since we want to inspect with TensorBoard below."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:tf_encrypted:Tensorflow encrypted is dumping computation traces\n",
      "INFO:tf_encrypted:Writing event and trace files to '/tmp/tensorboard'\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "('Tensorflow encrypted is monitoring statistics for each', 'session.run() call using a tag')\n"
     ]
    }
   ],
   "source": [
    "%load_ext tensorboard.notebook\n",
    "\n",
    "TENSORBOARD_DIR = \"/tmp/tensorboard\"\n",
    "\n",
    "tfe.set_tfe_trace_flag(True)\n",
    "tfe.set_tfe_events_flag(True)\n",
    "tfe.set_log_directory(TENSORBOARD_DIR)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Session\n",
    "\n",
    "We here prepare a session that is ready to use and be interleaved with graph construction. Note that for this to work we have to specify all players up front."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:tf_encrypted:Players: ['server0', 'server1', 'server2', 'inputter', 'result-receiver']\n"
     ]
    }
   ],
   "source": [
    "tf.Session.reset('')\n",
    "tf.reset_default_graph()\n",
    "\n",
    "!rm -rf {TENSORBOARD_DIR}\n",
    "\n",
    "players = ['server0', 'server1', 'server2', 'inputter', 'result-receiver']\n",
    "tfe.set_config(tfe.LocalConfig(players))\n",
    "tfe.set_protocol(tfe.protocol.Pond())\n",
    "\n",
    "sess = tfe.Session(disable_optimizations=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can then create and use our queue, following how this would be done in ordinary TensorFlow."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "shape = (5, 5)\n",
    "\n",
    "q = tfe.queue.FIFOQueue(capacity=10, shape=shape)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "x = tfe.define_private_input('inputter', lambda: tf.fill(shape, 5))\n",
    "\n",
    "enqueue_op = q.enqueue(x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "WARNING:tensorflow:From /Users/dahl/work/tf-encrypted/tf-encrypted/examples/notebooks/utils.py:9: py_func (from tensorflow.python.ops.script_ops) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "tf.py_func is deprecated in TF V2. Instead, use\n",
      "    tf.py_function, which takes a python function which manipulates tf eager\n",
      "    tensors instead of numpy arrays. It's easy to convert a tf eager tensor to\n",
      "    an ndarray (just call tensor.numpy()) but having access to eager tensors\n",
      "    means `tf.py_function`s can use accelerators such as GPUs as well as\n",
      "    being differentiable using a gradient tape.\n",
      "    \n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "WARNING:tensorflow:From /Users/dahl/work/tf-encrypted/tf-encrypted/examples/notebooks/utils.py:9: py_func (from tensorflow.python.ops.script_ops) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "tf.py_func is deprecated in TF V2. Instead, use\n",
      "    tf.py_function, which takes a python function which manipulates tf eager\n",
      "    tensors instead of numpy arrays. It's easy to convert a tf eager tensor to\n",
      "    an ndarray (just call tensor.numpy()) but having access to eager tensors\n",
      "    means `tf.py_function`s can use accelerators such as GPUs as well as\n",
      "    being differentiable using a gradient tape.\n",
      "    \n"
     ]
    }
   ],
   "source": [
    "y = q.dequeue()\n",
    "z = y + y\n",
    "\n",
    "dequeue_op = tfe.define_output('result-receiver', z, print_in_notebook)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Queue status: 1/10\n"
     ]
    }
   ],
   "source": [
    "sess.run(enqueue_op, tag='enqueue')\n",
    "\n",
    "print(\"Queue status: {}/{}\".format(sess.run(q.size()), q.capacity))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[10. 10. 10. 10. 10.]\n",
      " [10. 10. 10. 10. 10.]\n",
      " [10. 10. 10. 10. 10.]\n",
      " [10. 10. 10. 10. 10.]\n",
      " [10. 10. 10. 10. 10.]]\n",
      "Queue status: 0/10\n"
     ]
    }
   ],
   "source": [
    "sess.run(dequeue_op, tag='dequeue')\n",
    "\n",
    "print(\"Queue status: {}/{}\".format(sess.run(q.size()), q.capacity))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Inspection"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Reusing TensorBoard on port 6010 (pid 64858), started 22:38:10 ago. (Use '!kill 64858' to kill it.)"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "\n",
       "        <iframe\n",
       "            width=\"100%\"\n",
       "            height=\"600\"\n",
       "            src=\"http://localhost:6010\"\n",
       "            frameborder=\"0\"\n",
       "            allowfullscreen\n",
       "        ></iframe>\n",
       "        "
      ],
      "text/plain": [
       "<IPython.lib.display.IFrame at 0x10befcc88>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "%tensorboard --logdir {TENSORBOARD_DIR}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.5.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
